home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 February / EnigmA AMIGA RUN 04 (1996)(G.R. Edizioni)(IT)[!][issue 1996-02][Skylink CD III].iso / earcd / comm2 / termsorc.lha / Extras / Source / term-source.lha / termMemory.c < prev    next >
C/C++ Source or Header  |  1995-09-26  |  9KB  |  421 lines

  1. /*
  2. **    termMemory.c
  3. **
  4. **    Memory management routines
  5. **
  6. **    Copyright © 1990-1995 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. */
  9.  
  10. #include "termGlobal.h"
  11.  
  12.     // Main memory pool puddle size
  13.  
  14. #define PUDDLE_SIZE 32768
  15.  
  16.     // Memory allocation data
  17.  
  18. STATIC struct SignalSemaphore    MemorySemaphore;
  19. STATIC APTR            MemoryPool;
  20.  
  21.     // Prototypes for pools.lib
  22.  
  23. APTR __asm AsmCreatePool(register __d0 ULONG MemFlags,register __d1 ULONG PuddleSize,register __d2 ULONG ThreshSize,register __a6 struct ExecBase *SysBase);
  24. VOID __asm AsmDeletePool(register __a0 APTR PoolHeader,register __a6 struct ExecBase *SysBase);
  25. APTR __asm AsmAllocPooled(register __a0 APTR PoolHeader, register __d0 ULONG Size,register __a6 struct ExecBase *SysBase);
  26. VOID __asm AsmFreePooled(register __a0 APTR PoolHeader,register __a1 APTR Memory,register __d0 ULONG MemSize,register __a6 struct ExecBase *SysBase);
  27.  
  28.     // Diagnostic data
  29.  
  30. typedef char (* __asm SegTrack(register __a0 ULONG Address,register __a1 ULONG *SegNum,register __a2 ULONG *Offset));
  31.  
  32. struct SegSem
  33. {
  34.     struct SignalSemaphore     seg_Semaphore;
  35.     SegTrack        *seg_Find;
  36. };
  37.  
  38. struct FirewallInfo
  39. {
  40.     ULONG            Checksum;
  41.  
  42.     ULONG            Address;
  43.     ULONG            TotalSize;
  44.     ULONG            ReturnAddress;
  45.     ULONG            Size;
  46.     ULONG            FillByte;
  47.  
  48.     ULONG            FirePre;
  49.     ULONG            FirePost;
  50. };
  51.  
  52. STATIC LONG            FirewallPre = 0,FirewallPost = 0;
  53. STATIC ULONG            FillByte = 1;
  54.  
  55. STATIC LONG            Smallest = -1,Largest = -1;
  56.  
  57.     /* MemorySetup():
  58.      *
  59.      *    Set up the main memory pool.
  60.      */
  61.  
  62. BOOLEAN
  63. MemorySetup()
  64. {
  65.     BOOL DosOpen = FALSE;
  66.  
  67.     if(!DOSBase)
  68.     {
  69.         if(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",37))
  70.             DosOpen = TRUE;
  71.     }
  72.  
  73.     if(DOSBase)
  74.     {
  75.         UBYTE LocalBuffer[256];
  76.  
  77.         if(GetVar("TERMPREALLOC",LocalBuffer,256,NULL) > 0)
  78.         {
  79.             if(StrToLong(LocalBuffer,&FirewallPre) > 0)
  80.             {
  81.                 if(FirewallPre < 16)
  82.                     FirewallPre = 16;
  83.  
  84.                 FirewallPost = 16;
  85.  
  86.                 if(GetVar("TERMPOSTALLOC",LocalBuffer,256,NULL) > 0)
  87.                 {
  88.                     if(StrToLong(LocalBuffer,&FirewallPre) <= 0)
  89.                         FirewallPost = 16;
  90.                 }
  91.  
  92.                 FirewallPre    = (FirewallPre + 15) & ~15;
  93.                 FirewallPost    = (FirewallPost + 15) & ~15;
  94.  
  95.                 if(!FirewallPost)
  96.                     FirewallPost = 16;
  97.             }
  98.             else
  99.                 FirewallPost = 0;
  100.         }
  101.  
  102.         if(DosOpen)
  103.         {
  104.             CloseLibrary((struct Library *)DOSBase);
  105.             DOSBase = NULL;
  106.         }
  107.     }
  108.  
  109.     InitSemaphore(&MemorySemaphore);
  110.  
  111.     if(MemoryPool = AsmCreatePool(MEMF_PUBLIC | MEMF_ANY,PUDDLE_SIZE,PUDDLE_SIZE,SysBase))
  112.         return(TRUE);
  113.     else
  114.         return(FALSE);
  115. }
  116.  
  117.     /* MemoryCleanup():
  118.      *
  119.      *    Clean up the main memory pool.
  120.      */
  121.  
  122. VOID
  123. MemoryCleanup()
  124. {
  125.     if(Smallest != -1)
  126.     {
  127.         kprintf("term stats: smallest allocation was %ld bytes\n",Smallest);
  128.         Smallest = -1;
  129.     }
  130.  
  131.     if(Largest != -1)
  132.     {
  133.         kprintf("term stats: largest allocation was %ld bytes\n",Largest);
  134.         Largest = -1;
  135.     }
  136.  
  137.     if(MemoryPool)
  138.     {
  139.         AsmDeletePool(MemoryPool,SysBase);
  140.  
  141.         MemoryPool = NULL;
  142.     }
  143. }
  144.  
  145.     /* FreeVecPooled(APTR Memory):
  146.      *
  147.      *    Free a memory chunk.
  148.      */
  149.  
  150. VOID __asm
  151. FreeVecPooledLocal(register __a0 APTR Memory,register __a1 ULONG ReturnAddress)
  152. {
  153.     if(Memory && MemoryPool)
  154.     {
  155.         ULONG *Data = (ULONG *)Memory;
  156.  
  157.         ObtainSemaphore(&MemorySemaphore);
  158.  
  159.         if(FirewallPre)
  160.         {
  161.             struct FirewallInfo *Info;
  162.             ULONG Sum,*Thing;
  163.             WORD i;
  164.  
  165.             Info = (struct FirewallInfo *)(((ULONG)Memory) - (sizeof(struct FirewallInfo) + FirewallPre));
  166.  
  167.             for(Sum = 0, i = 1, Thing = &Info -> Address ; i < sizeof(struct FirewallInfo) / sizeof(ULONG) ; i++)
  168.                 Sum += Thing[i];
  169.  
  170.             if(Info -> Checksum == ~Sum && Memory == (APTR)Info -> Address)
  171.             {
  172.                 UBYTE *Data;
  173.                 LONG i;
  174.                 BOOL AllocationProblem = FALSE;
  175.  
  176.                 Data = (UBYTE *)Info -> FirePre;
  177.  
  178.                 for(i = 0 ; i < FirewallPre ; i++)
  179.                 {
  180.                     if(Data[i] != Info -> FillByte)
  181.                     {
  182.                         LONG j;
  183.  
  184.                         AllocationProblem = TRUE;
  185.  
  186.                         kprintf("term: Allocation @ 0x%08lx, Size %ld got stomped on, %ld bytes trashed before, FillByte %02lx:",Memory,Info -> Size,FirewallPre - i,Info -> FillByte);
  187.  
  188.                         Data = &Data[i];
  189.  
  190.                         for(j = 0 ; j < FirewallPre - i ; j++)
  191.                         {
  192.                             if(!(j & 7))
  193.                                 kprintf("\n      %08lx: ",&Data[j]);
  194.  
  195.                             kprintf("%02lx ",Data[j]);
  196.                         }
  197.  
  198.                         kprintf("\n");
  199.  
  200.                         break;
  201.                     }
  202.                 }
  203.  
  204.                 Data = (UBYTE *)Info -> FirePost;
  205.  
  206.                 for(i = FirewallPost - 1 ; i >= 0 ; i--)
  207.                 {
  208.                     if(Data[i] != Info -> FillByte)
  209.                     {
  210.                         LONG j;
  211.  
  212.                         Data = (UBYTE *)Info -> FirePost;
  213.  
  214.                         if(AllocationProblem)
  215.                             kprintf("      %ld bytes trashed after:",i + 1);
  216.                         else
  217.                             kprintf("term: Allocation @ 0x%08lx, Size %ld got stomped on, %ld bytes trashed after, FillByte 0x%02lx:",Memory,Info -> Size,i + 1,Info -> FillByte);
  218.  
  219.                         AllocationProblem = TRUE;
  220.  
  221.                         for(j = 0 ; j <= i ; j++)
  222.                         {
  223.                             if(!(j & 7))
  224.                                 kprintf("\n      %08lx: ",&Data[j]);
  225.  
  226.                             kprintf("%02lx ",Data[j]);
  227.                         }
  228.  
  229.                         kprintf("\n");
  230.  
  231.                         break;
  232.                     }
  233.                 }
  234.  
  235.                 if(AllocationProblem)
  236.                 {
  237.                     struct SegSem *SegTracker;
  238.  
  239.                     Forbid();
  240.  
  241.                     if(SegTracker = (struct SegSem *)FindSemaphore("SegTracker"))
  242.                     {
  243.                         char LocalBuffer[256];
  244.                         ULONG Segment,Offset;
  245.                         char *Name;
  246.  
  247.                         kprintf("\n");
  248.  
  249.                         if(Name = (*SegTracker -> seg_Find)(Info -> ReturnAddress,&Segment,&Offset))
  250.                         {
  251.                             CopyMem(Name,LocalBuffer,255);
  252.                             LocalBuffer[255] = 0;
  253.  
  254.                             kprintf("      Alloc by |%s| %lx:%lx\n",LocalBuffer,Segment,Offset);
  255.                         }
  256.  
  257.                         if(Name = (*SegTracker -> seg_Find)(ReturnAddress,&Segment,&Offset))
  258.                         {
  259.                             CopyMem(Name,LocalBuffer,255);
  260.                             LocalBuffer[255] = 0;
  261.  
  262.                             kprintf("       Free by |%s| %lx:%lx\n",LocalBuffer,Segment,Offset);
  263.                         }
  264.                     }
  265.  
  266.                     Permit();
  267.                 }
  268.  
  269.                 AsmFreePooled(MemoryPool,Info,Info -> TotalSize,SysBase);
  270.             }
  271.             else
  272.             {
  273.                 struct SegSem *SegTracker;
  274.  
  275.                 Forbid();
  276.  
  277.                 if(SegTracker = (struct SegSem *)FindSemaphore("SegTracker"))
  278.                 {
  279.                     char LocalBuffer[256];
  280.                     ULONG Segment,Offset;
  281.                     char *Name;
  282.  
  283.                     if(Name = (*SegTracker -> seg_Find)(ReturnAddress,&Segment,&Offset))
  284.                     {
  285.                         CopyMem(Name,LocalBuffer,255);
  286.                         LocalBuffer[255] = 0;
  287.  
  288.                         kprintf("       Bogus free from 0x%08lx by |%s| %lx:%lx\n",Memory,LocalBuffer,Segment,Offset);
  289.                     }
  290.                 }
  291.  
  292.                 Permit();
  293.             }
  294.         }
  295.         else
  296.             AsmFreePooled(MemoryPool,&Data[-1],Data[-1],SysBase);
  297.  
  298.         ReleaseSemaphore(&MemorySemaphore);
  299.     }
  300. }
  301.  
  302.     /* AllocVecPooled(ULONG Size,ULONG Flags):
  303.      *
  304.      *    Allocate a memory chunk from the main memory pool and
  305.      *    remember its size.
  306.      */
  307.  
  308. APTR __asm
  309. AllocVecPooledLocal(register __d0 ULONG Size,register __d1 ULONG Flags,register __a0 ULONG ReturnAddr)
  310. {
  311.     if(MemoryPool)
  312.     {
  313.         ObtainSemaphore(&MemorySemaphore);
  314.  
  315.         if(FirewallPre)
  316.         {
  317.             struct FirewallInfo *Info;
  318.             ULONG FireSize;
  319.             ULONG RoundSize = (Size + 3) & ~3;
  320.  
  321.             if(Smallest == -1)
  322.                 Smallest = Size;
  323.  
  324.             if(Largest == -1)
  325.                 Largest = Size;
  326.  
  327.             if(Size < Smallest)
  328.                 Smallest = Size;
  329.  
  330.             if(Size > Largest)
  331.                 Largest = Size;
  332.  
  333.             FireSize = sizeof(struct FirewallInfo) + FirewallPre + RoundSize + FirewallPost;
  334.  
  335.             if(Info = (struct FirewallInfo *)AsmAllocPooled(MemoryPool,FireSize,SysBase))
  336.             {
  337.                 ULONG *Data,Sum,*Thing;
  338.                 WORD i;
  339.  
  340.                 Info -> Address        = ((ULONG)Info) + sizeof(struct FirewallInfo) + FirewallPre;
  341.                 Info -> TotalSize    = FireSize;
  342.                 Info -> ReturnAddress    = ReturnAddr;
  343.                 Info -> Size        = Size;
  344.                 Info -> FillByte    = FillByte;
  345.  
  346.                 Info -> FirePre        = (ULONG)&Info[1];
  347.                 Info -> FirePost    = Info -> FirePre + FirewallPre + RoundSize;
  348.  
  349.                 memset((APTR)(Info -> FirePre),FillByte,FirewallPre);
  350.                 memset((APTR)(Info -> FirePost),FillByte,FirewallPost);
  351.  
  352.                 for(Sum = 0, i = 1, Thing = &Info -> Address ; i < sizeof(struct FirewallInfo) / sizeof(ULONG) ; i++)
  353.                     Sum += Thing[i];
  354.  
  355.                 Info -> Checksum = ~Sum;
  356.  
  357.                 FillByte = (FillByte + 2) & 0xFF;
  358.  
  359.                 Data = (ULONG *)Info -> Address;
  360.  
  361.                 ReleaseSemaphore(&MemorySemaphore);
  362.  
  363.                 if(Flags & MEMF_CLEAR)
  364.                 {
  365.                     register ULONG *Memory = Data;
  366.  
  367.                     Size = RoundSize / sizeof(ULONG) - 1;
  368.  
  369.                     do
  370.                         *Memory++ = 0;
  371.                     while(Size--);
  372.                 }
  373.                 else
  374.                 {
  375.                     register ULONG *Memory = Data;
  376.  
  377.                     Size = RoundSize / sizeof(ULONG) - 1;
  378.  
  379.                     do
  380.                         *Memory++ = 0xDEADBEEF;
  381.                     while(Size--);
  382.                 }
  383.  
  384.                 return((APTR)Data);
  385.             }
  386.         }
  387.         else
  388.         {
  389.             ULONG *Data;
  390.  
  391.             Size = (Size + sizeof(ULONG) + 3) & ~3;
  392.  
  393.             if(Data = (ULONG *)AsmAllocPooled(MemoryPool,Size,SysBase))
  394.             {
  395.                 ReleaseSemaphore(&MemorySemaphore);
  396.  
  397.                 *Data++ = Size;
  398.  
  399.                     // Zero the chunk if necessary
  400.  
  401.                 if(Flags & MEMF_CLEAR)
  402.                 {
  403.                     register ULONG *Memory = Data;
  404.  
  405.                     Size = Size / sizeof(ULONG) - 2;
  406.  
  407.                     do
  408.                         *Memory++ = 0;
  409.                     while(Size--);
  410.                 }
  411.  
  412.                 return((APTR)Data);
  413.             }
  414.         }
  415.  
  416.         ReleaseSemaphore(&MemorySemaphore);
  417.     }
  418.  
  419.     return(NULL);
  420. }
  421.